/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 * <p>
 * https://www.renren.io
 * <p>
 * 版权所有，侵权必究！
 */

package io.renren.controller;

import cn.hutool.core.bean.BeanUtil;
import io.renren.common.utils.Constant;
import io.renren.common.utils.HttpReqUtil;
import io.renren.common.utils.R;
import io.renren.entity.EslRefreshLogEntity;
import io.renren.param.ApHeartBeatData;
import io.renren.param.ApHeartBeatParam;
import io.renren.param.EslHeartBeatData;
import io.renren.param.EslHeartBeatParam;
import io.renren.service.EslRefreshLogService;
import io.renren.service.EslRefreshResultService;
import io.renren.service.EslWorkingService;
import io.renren.vo.EslReturnDataVo;
import io.renren.vo.EslReturnVo;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * esl接口
 *
 * @author Mark sunlightcs@gmail.com
 */
@RestController
@RequestMapping("/ew")
@Api(tags = "esl接口")
@Slf4j
public class ApiEslController {

    @Autowired
    private EslWorkingService eslWorkingService;

    @Autowired
    private EslRefreshLogService eslRefreshLogService;

    @Autowired
    private EslRefreshResultService eslRefreshResultService;

    @RequestMapping("httpHandler")
    public R httpHandler(@RequestBody Map<String, Object> map) throws InvocationTargetException, IllegalAccessException {
//        log.debug("心跳消息：{}",JSONUtil.parse(map));

        Integer statusNo = -1;
        String type, user;
        com.alibaba.fastjson.JSONArray data;
        statusNo = (Integer) map.get("status_no");
        type = (String) map.get("type");
        user = (String) map.get("user");
        data = (com.alibaba.fastjson.JSONArray) map.get("data");

        /** status_no = 0，表示成功
         * type值表示上行消息类型。ESL_HB_STATUS - 价签心跳；AP_STATUS - 基站心跳；
         * UNBIND_STATUS - 价签解绑通知；STARTUP - ESL已经启动；
         **/
        if (statusNo == 0) {
            switch (type) {
                case "AP_STATUS":
                    ApHeartBeatParam apHeartBeatParam = new ApHeartBeatParam();
                    List<ApHeartBeatData> apHeartBeatDataList = new ArrayList<>();
                    for (Object datum : data) {
                        ApHeartBeatData heartBeatData = new ApHeartBeatData();
                        BeanUtil.copyProperties(datum, heartBeatData);
                        apHeartBeatDataList.add(heartBeatData);
                    }
                    apHeartBeatParam.setData(apHeartBeatDataList);
                    apHeartBeatParam.setStatusNo(String.valueOf(statusNo));
                    apHeartBeatParam.setType(type);
                    apHeartBeatParam.setUser(user);
                    apHB(apHeartBeatParam);
                    break;
                case "ESL_HB_STATUS":
                    EslHeartBeatParam eslHeartBeatParam = new EslHeartBeatParam();
                    List<EslHeartBeatData> eslHeartBeatDataList = new ArrayList<>();
                    for (Object datum : data) {
                        EslHeartBeatData heartBeatData = new EslHeartBeatData();
                        BeanUtil.copyProperties(datum, heartBeatData);
                        eslHeartBeatDataList.add(heartBeatData);
                    }
                    eslHeartBeatParam.setData(eslHeartBeatDataList);
                    eslHeartBeatParam.setUser(user);
                    eslHeartBeatParam.setStatusNo(String.valueOf(statusNo));
                    eslHeartBeatParam.setType(type);
                    eslHB(eslHeartBeatParam);
                    break;
                case "UNBIND_STATUS":
                    log.info("接收到价签解绑通知");
                    break;
                case "STARTUP":
                    log.info("接收到EW启动通知");
                    break;
            }
        }

        return R.ok();
    }

    @PostMapping("eslHB")
    public R eslHB(@RequestBody EslHeartBeatParam param) {
//    public R eslHB(@RequestBody List<EslHeartBeatData> param) {
        // esl heart beat
        /*{
            "status_no": "0",
                "type": "ESL_HB_STATUS",
                "user": "aaaa",
                "data": [{
                    "ap_id": "2",
                    "last_hb_time": "0",
                    "firmware_id": "",
                    "rf_power": "192.168.9.253",
                    "reserve": "NONE",
                    "set_wor": "2",
                    "nfc": "standby",
                    "esl_id": "DC:07:C1:01:01:4C",
                    "battery": "14",
                    "user": "NONE",
                    "rom_version": ""
        }]
        }*/
        eslWorkingService.eslHeartBeat(param);
        return R.ok();
    }

    @PostMapping("apHB")
    public R apHB(@RequestBody ApHeartBeatParam param) {
//    public R apHB(@RequestBody List<ApHeartBeatData> param) {
        // ap heart beat
        /*{
            "status_no": "0",
                "type": "AP_STATUS",
                "data": [{
                    "ap_id": "2",
                    "listen_port": "0",
                    "online_begin_time": "",
                    "ip": "192.168.9.253",
                    "channel": "NONE",
                    "version": "2",
                    "work_mode": "standby",
                    "mac": "DC:07:C1:01:01:4C",
                    "sequence": "14",
                    "netmask": "NONE",
                    "last_work_time": "",
                    "sn": "22222222222",
                    "user": "default",
                    "gateway": "NONE",
                    "status": "offline",
                    "desc": "NONE"
        }]
        }*/

        eslWorkingService.apHeartBeat(param);
        return R.ok();
    }

    @RequestMapping("eslRefreshResult")
//    public R eslRefreshResult(@RequestBody Map<String, Object> map) throws InvocationTargetException, IllegalAccessException {
//        JSON res = JSONUtil.parse(map);
//        log.info("eslRefreshResult：{}", res);
//
//        JSONArray datas = (JSONArray) map.get("data");
//        JSONObject json = (JSONObject) datas.get(0);
//        Integer statusNo = (Integer) json.get("status_no");
//        String eslId = (String) json.get("esl_id");
//        String type = (String) json.get("type");

    public R eslRefreshResult(@RequestBody EslReturnVo vo) {
        log.info("eslRefreshResult：{}", vo);

        //通讯失败 返回例子
//        {"data":[{"ap_id":"5","ap_mac":"98:6D:35:73:F6:1C","last_esl_ack":0,"rf_power":132,"sales_no":"","errmsg":"","sid":"3780952540","last_hb_time":"1642003704085","status_no":203,"esl_id":"51-E6-6E-D0","last_payload_type":"UPDATE","retry":3}],"type":"ESL_UPDATE_ACK","status_no":0,"user":"wpE44jCAAAOFmb7eqaoYUKR8VkZPVenQ"}


        //达到系统最大重试次数，通讯失败,重推
        List<EslReturnDataVo> dataVos = vo.getData();
        for (EslReturnDataVo dataVo : dataVos) {
            if (Constant.ESL_REFRESH_TYPE_UPDATE_ACK.equals(vo.getType())) {
                eslRefreshResultService.save(EslReturnDataVo.convertFor(dataVo));
            }

            //通迅失败重推
            if (dataVo.getStatusNo() == 203) {
                EslRefreshLogEntity eslRefreshLogEntity = eslRefreshLogService.queryByEslId(dataVo.getEslId());

                //刷新esl
                if (eslRefreshLogEntity.getRefreshNum() >= 3) {
                    log.warn("eslId = {}, sid = {}, 已重推3次，不再重推", eslRefreshLogEntity.getEslId(), eslRefreshLogEntity.getSid());
                } else {
                    String jsonStr = eslRefreshLogEntity.getParams();
                    String url = eslRefreshLogEntity.getEwUrl();
                    eslRefreshLogEntity.setRefreshNum(eslRefreshLogEntity.getRefreshNum() + 1);
                    eslRefreshLogEntity.setUpdateTime(new Date());
                    eslRefreshLogService.saveOrUpdate(eslRefreshLogEntity);

                    String result = HttpReqUtil.doPut(url, jsonStr);

                    log.info("repush result is {}", result);
                }
            }
        }

        return R.ok();
    }
}
